/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Parser;

import compiler.CMinusCompiler;
import lowlevel.Function;
import lowlevel.Operand;
import lowlevel.Operation;

/**
 *
 * @author maxmuhlenkamp
 */
public class AssignExpression extends Expression {
    Identifier variable;
    Expression assignment;
    
    public AssignExpression(Identifier variable, Expression assignment){
        this.variable = variable;
        this.assignment = assignment;
    }

    @Override
    void print(String indent) {
        
        CMinusParser.oFile.println(indent + "AssignExpression:");
        CMinusParser.oFile.println(indent + "  =");
        variable.print(indent + "  ");
        assignment.print(indent + "  ");
        CMinusParser.oFile.flush();
    }

    @Override
    public void genLLCode(Function func) {
        assignment.genLLCode(func);
        
        //search local function table before global table
        //if(CMinusCompiler.globalHash.containsKey(variable.idName)){
        if(func.getTable().containsKey(variable.idName)){
            //regNum = (int)CMinusCompiler.globalHash.get(variable.idName);
            regNum = (int)func.getTable().get(variable.idName);
            
            Operation assign = new Operation(Operation.OperationType.ASSIGN, func.getCurrBlock());
            Operand dest = new Operand(Operand.OperandType.REGISTER, regNum);
            Operand src = new Operand(Operand.OperandType.REGISTER, assignment.getRegNum());
            
            assign.setDestOperand(0, dest);
            assign.setSrcOperand(0, src);
            func.getCurrBlock().appendOper(assign);
        }
        else if(CMinusCompiler.globalHash.containsKey(variable.idName)){
            // store the information
            regNum = assignment.getRegNum();
            Operation store = new Operation(Operation.OperationType.STORE_I, func.getCurrBlock());
            Operand src0 = new Operand(Operand.OperandType.REGISTER, assignment.getRegNum());
            Operand src1 = new Operand(Operand.OperandType.STRING, variable.idName);
            Operand src2;
            if(variable.location == null){
                src2 = new Operand(Operand.OperandType.INTEGER, 0);
            }
            else{
                src2 = new Operand(Operand.OperandType.REGISTER, variable.location.getRegNum());
            }
            
            store.setSrcOperand(0, src0);
            store.setSrcOperand(1, src1);
            store.setSrcOperand(2, src2);
            
            func.getCurrBlock().appendOper(store);
        }
        else{
            System.err.println("The assign expression variable was not found in the symbol table");
        }
    }
}
